import json
import os

import pymysql

from utils.singleton import singleton


@singleton
class MySqlUtil:

    def __init__(self):
        self.__connect = self.__get_connect()
        self.__cursor = self.__get_cursor()

    @staticmethod
    def __get_connect():
        """
        获取数据库连接
        :return:
        """
        current_path = os.path.dirname(os.path.abspath(__file__))
        root_path = os.path.dirname(current_path) + '/resource/config.json'
        with open(root_path, 'r') as f:
            config = json.load(f)
        dataSource = {
            'host': config['dataSource']['host'],
            'port': config['dataSource']['port'],
            'user': config['dataSource']['user'],
            'password': config['dataSource']['password'],
            'database': config['dataSource']['database'],
            'charset': config['dataSource']['charset'],
            'autocommit': bool(config['dataSource']['autocommit'])
        }
        return pymysql.connect(**dataSource)

    def __get_cursor(self):
        """
        获取游标对象
        :return:
        """
        return self.__connect.cursor()

    def get_count(self, sql, args):
        cursor = self.__cursor
        try:
            cursor.execute(sql, args)
            datas = cursor.fetchall()
            result = datas[0][0]
        except BaseException as e:
            raise Exception('Error: unable to fetch data:', e)
        return result

    def query(self, sql, args):
        cursor = self.__cursor
        result = []
        try:
            cursor.execute(sql, args)
            datas = cursor.fetchall()
            cols = cursor.description
            for data in datas:
                data_dic = {}
                for index, col in enumerate(cols):
                    field_name = col[0]
                    data_dic.setdefault(field_name, data[index])
                result.append(data_dic)
            return result
        except BaseException as e:
            raise Exception('Error: unable to fetch data:', e)

    def execute(self, sql, args):
        cursor, connect = self.__cursor, self.__connect
        try:
            cursor.execute(sql, args)
            # connect.commit()
        except BaseException as e:
            connect.rollback()
            raise Exception('Error: unable to execute db:', e)
